package com.itfreer.gis.server.mine;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 定义四维在线切片转换类
 */
public class MineOnlineTiles {

	private static Map<SocketTimeoutException, String> tempMap = new HashMap<SocketTimeoutException, String>();

	/**
	 * 远程文件下载
	 *
	 * @param url  下载地址
	 * @param file 保存文件地址
	 */
	public static boolean download(String zxystr, URL url, File file) throws IOException {
		boolean flag = true;
		DataOutputStream dos = null;
		DataInputStream dis = null;
		try {
			if (!file.getParentFile().exists())
				file.getParentFile().mkdirs();
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
			conn.setConnectTimeout(6000);
			conn.setReadTimeout(20000);
			conn.connect();
			dos = new DataOutputStream(new FileOutputStream(file));
			dis = new DataInputStream(conn.getInputStream());
			byte[] data = new byte[2048];
			int i = 0;
			while ((i = dis.read(data)) != -1) {
				dos.write(data, 0, i);
			}
			dos.flush();
		} catch (SocketTimeoutException e) {
			tempMap.put(e, zxystr);
			System.out.println(zxystr);
			System.out.println(e);
		} catch (IOException e) {
			flag = false;
			System.out.println(e);
		} catch (Exception e) {
			flag = false;
			System.out.println(e);
		} finally {
			if (dis != null)
				dis.close();
			if (dos != null)
				dos.close();
		}
		return flag;
	}

	/**
	 * 根据经度获取切片规范下的行号
	 *
	 * @param lon
	 * @param zoom
	 * @return
	 */
	public static int getOSMTileXFromLongitude(double lon, int zoom) {
		return (int) (Math.floor((lon + 180) / 360 * Math.pow(2, zoom)));
	}

	/**
	 * 根据纬度获取切片规范下的列号
	 *
	 * @param lat
	 * @param zoom
	 * @return
	 */
	public static int getOSMTileYFromLatitude(double lat, int zoom) {
		return (int) (Math
				.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2
						* Math.pow(2, zoom)));
	}

	public static void main(String[] arg) throws IOException {
//        double[] extent = {68, 11, 135, 54};//中国
//        double[] extent = {113, 23, 129, 35.26};//华东（广州-釜山）
		double[] extent = { 117, 26, 123, 32 };// 浙江
//        for (int z = 10; z < 11; z++) {
//        double[] extent = {-180, -90, 180, 90};
		for (int z = 14; z <= 14; z++) {
			// 计算行列号(使用瓦片的中心点经纬度计算)
			// 起始结束行
			int minR = getOSMTileYFromLatitude(extent[3], z);
			int maxR = getOSMTileYFromLatitude(extent[1], z);
			// 起始结束列
			int minC = getOSMTileXFromLongitude(extent[0], z);
			int maxC = getOSMTileXFromLongitude(extent[2], z);
//            for (int y = minR; y <= maxR; y++) {
			for (int y = 6937; y <= maxR; y++) {
				for (int x = minC; x <= maxC; x++) {
					String urlstr = "https://maps.tilehosting.com/data/v3/" + z + "/" + x + "/" + y
							+ ".pbf?key=yzgDrAunRjJjwhG6D3u7";
//                      String urlstr = "https://b.tiles.mapbox.com/v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7/" + z + "/" + x + "/" + y +".vector.pbf?access_token=pk.eyJ1IjoibHhxanNzIiwiYSI6ImNqY3NkanRjajB1MWwzM3MwcnA0dDJrYngifQ.ApTVfmm2zBM_kF22DvtowQ";
//                    String urlstr = "http://demo.zjditu.cn/vtiles/tdt_zj/" + z + "/" + x + "/" + (y-8054) +".mvt?v=20180831"; //天地图服务器t0-t8间选一个
//                    String urlstr = "http://t0.tianditu.com/DataServer?T=vec_w&x="+x+"&y="+y+"&l="+z; //天地图服务器t0-t8间选一个
//                    String urlstr = "http://mt2.google.cn/vt/lyrs=m&scale=1&hl=zh-CN&gl=cn&x="+x+"&y="+y+"&z="+z; //谷歌地图服务器t0-t2间选一个
//                    String urlstr = "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x="+x+"&y="+y+"&z="+z+"&&styles=pl&udt=20170712&scaler=1&p=1"; //百度地图（加密过的）
//                    String urlstr = "http://c.tile.opencyclemap.org/cycle/" + z + "/" + x + "/" + y + ".png"; //osm地图
//                    String urlstr = "http://wprd04.is.autonavi.com/appmaptile?x="+x+"&y="+y+"&z="+z+"&lang=zh_cn&size=1&scl=1&style=8"; //高德地图(6：影像，7：矢量，8：影像路网)

					DecimalFormat df = new DecimalFormat("0.00");
					System.out.println("X:(" + minC + "->" + maxC + "); Y:(" + minR + "->" + maxR + ")。");
					System.out.println("第" + z + "级总共将会有：" + (maxC - minC + 1) + "个文件夹，每个有" + (maxR - minR + 1)
							+ "个文件;总下载：" + (maxC - minC + 1) * (maxR - minR + 1) + "个文件；该级别下载进度："
							+ df.format(100 * (y - minR) / (double) (maxR - minR + 1)) + "%");
					System.out.println(urlstr);

					String path = null;
//                    if (type.equals("ArcGIS")) {
//                        //ArcGIS格式瓦片下载
//                        path = getTDTilesForArcGISPath(x, y, z);
//                    } else {
//                        //一般格式瓦片下载
//                        path = getTDTilesForCustomPath(x, y, z);
//                    }
//                    path = getTDTilesForCustomPathMvt(x,y,z);
					path = getOpenstreetForCustomPathMvt(x, y, z);

					File file = new File(path);
					URL url = new URL(urlstr);
					String zxyStr = z + "/" + x + "/" + y;
					download(zxyStr, url, file);
				}
			}
		}
		Iterator<SocketTimeoutException> iterator = tempMap.keySet().iterator();
		while (iterator.hasNext()) {
			Object key = iterator.next();
			System.out.println("tmp.get(key) is :" + tempMap.get(key));
		}
	}

	public static String getTDTilesForArcGISPath(int x, int y, int z) {
		String l = "L" + String.format("%02d", z);
		String r = "R" + makePath(y);
		String c = "C" + makePath(x);
		String path = "tile/" + l + File.separator + r + File.separator + c + ".png";
		return path;
	}

	public static String getTDTilesForCustomPath(int x, int y, int z) {
		String path = "tile/" + z + File.separator + y + File.separator + x + ".png";
		return path;
	}

	public static String getTDTilesForCustomPathMvt(int x, int y, int z) {
		String path = "tileMvt/" + z + File.separator + y + File.separator + x + ".mvt";
		return path;
	}

	public static String getOpenstreetForCustomPathMvt(int x, int y, int z) {
		String path = "tileOpenStreet/" + z + File.separator + x + File.separator + y + ".pbf";
		return path;
	}

	private static String makePath(int num) {
		String str = Integer.toHexString(num);
		// ArcGIS行列都是8位长度
		while (str.length() < 8) {
			str = "0" + str;
		}
		return str;
	}
}
